package com.ouc.eddyAlgorithm.utils;

import java.math.BigDecimal;

/**
 * OW算法识别涡旋
 */
public class OWEddyDetectUtil {

  /**
   * 获取单个点的W值
   * 通过九宫格方式求偏导
   * 以逆时针方向，左为1，上为2，右为3，下为4
   *
   * @param v1 左侧v分量
   * @param v3 右侧v分量
   * @param u1 左侧u分量
   * @param u2 上侧u分量
   * @param u3 右侧u分量
   * @param u4 下侧u分量
   * @param x1 左侧x坐标
   * @param x3 右侧x坐标
   * @param y2 上侧y坐标
   * @param y4 下侧y坐标
   * @return 该点的w值
   */
  public static float getOneW(float v1, float v3, float u1, float u2, float u3, float u4, float x1, float x3, float y2, float y4) {
    if (Float.isNaN(v1) || Float.isNaN(v3) || Float.isNaN(u1) || Float.isNaN(u2) || Float.isNaN(u3) || Float.isNaN(u4)) {
      return Float.NaN;
    }
    return (float) (4 * (((v3 - v1) / (x3 - x1)) * ((u4 - u2) / (y4 - y2)) + Math.pow((u3 - u1) / (x3 - x1), 2)));
  }

  /**
   * 获取区域w数组的标准差
   * 如果w值为NaN，则去除该值
   *
   * @param w 区域 w 数组
   * @return
   */
  public static float getWStandard(float[][] w) {
    int count = w.length * w[0].length;
    BigDecimal sum = BigDecimal.ZERO;
    for (int i = 0; i < w.length; i++) {
      for (int j = 0; j < w[0].length; j++) {
        if (Float.isNaN(w[i][j])) {
          count--;
        } else {
          sum = sum.add(BigDecimal.valueOf(w[i][j]));
        }
      }
    }
    float avg = sum.divide(BigDecimal.valueOf(count), 4, BigDecimal.ROUND_HALF_UP).floatValue(); //平均数

    double variance = 0;  //方差
    for (int i = 0; i < w.length; i++) {
      for (int j = 0; j < w[0].length; j++) {
        if (!Float.isNaN(w[i][j])) {
          variance += Math.pow(w[i][j] - avg, 2);
        }
      }
    }

    return BigDecimal.valueOf(Math.sqrt(variance))
        .divide(BigDecimal.valueOf(count), 4, BigDecimal.ROUND_HALF_UP).floatValue();//四舍五入保留4位小数
  }


}
